﻿// Copyright (c) 2012 - 2020 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2018-12-05 version 3.1.5 Jared Zheng <jaredz at outlook dot com>

#include "stdafx.h"
#include "resource.h"
#include "network.h"
#include "servermap.h"
#include "ServerLoader.h"
#include "AuthorDlg.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// CAuthorDlg
XBEGIN_DLG_ID_WND_EXCHANGE( CAuthorDlg )
XDLG_ID_WND( IDC_CONNECT_CENTER,   m_ConnectCenter )
XDLG_ID_WND( IDC_CONNECT_AUTHORDB, m_ConnectAuthorDB )
XDLG_ID_WND( IDC_TCP_EXTERNAL,     m_TCPExternal )
XDLG_ID_WND( IDC_UDP_TO_MASTER,    m_UDPListenMaster )
XDLG_ID_WND( IDC_AUTHOR_INFO,      m_ServerInfo )
XDLG_ID_WND( IDD_MASTER,           m_MasterSvr )
XEND_DLG_ID_WND_EXCHANGE( CXDlg )

CAuthorDlg::CAuthorDlg(void)
: m_uAuthorOnline(0)
, m_uAuthorTotal(0)
, m_uAuthorLoad(0)
, m_uMasterCount(0)
, m_uMasterOnline(0)
, m_uMasterTotal(0)
{
}

CAuthorDlg::~CAuthorDlg(void)
{
}

LRESULT CAuthorDlg::OnInitDialog(void)
{
    RECT rc;
    GetClientRect(&rc);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);

    m_MasterSvr.MoveWindow(0, rc.top, rc.right, (rc.bottom - rc.top));
    //
    CStringFix strTemp;
    strTemp.Load(IDC_CONNECT_CENTER);
    m_ConnectCenter.SetWindowText(*strTemp);

    strTemp.Load(IDC_CONNECT_AUTHORDB);
    m_ConnectAuthorDB.SetWindowText(*strTemp);

    strTemp.Load(IDC_TCP_EXTERNAL);
    m_TCPExternal.SetWindowText(*strTemp);

    strTemp.Load(IDC_UDP_TO_MASTER);
    m_UDPListenMaster.SetWindowText(*strTemp);
    //
    InitServerData(PAKT_MASTER);
    return TRUE;
}

LRESULT CAuthorDlg::OnSize(WPARAM, LPARAM lParam, BOOL&)
{
    RECT rc   = { 0 };
    rc.right  = (Long)LOWORD(lParam);
    rc.bottom = (Long)HIWORD(lParam);

    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    m_ServerInfo.MoveWindow(0, rc.top, rc.right, DLG_ITEM_HEIGHT);

    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    m_MasterSvr.MoveWindow(0, rc.top, rc.right, (rc.bottom - rc.top));

    rc.right /=2;
    if (rc.right > DLG_ITEM_WIDTH)
    {
        m_ConnectCenter.MoveWindow(0, 0, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
        m_ConnectAuthorDB.MoveWindow((rc.right + DLG_ITEM_GRAP), 0, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));

        rc.top = (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
        m_TCPExternal.MoveWindow(0, rc.top, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
        m_UDPListenMaster.MoveWindow((rc.right + DLG_ITEM_GRAP), rc.top, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
    }
    return 0;
}

void CAuthorDlg::OnLive(bool bStart)
{
    CStringFix strTemp;
    if (bStart)
    {
        CStrAddr strAddr;
        strTemp.Load(IDC_TCP_EXTERNAL);
        GServerLoaderInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_AUTHOR, CServerConfig::CFG_LOAD_NONE, strAddr);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);
        m_TCPExternal.SetWindowText(*strTemp);
    }
    else
    {
        strTemp.Load(IDC_CONNECT_CENTER);
        m_ConnectCenter.SetWindowText(*strTemp);

        strTemp.Load(IDC_CONNECT_AUTHORDB);
        m_ConnectAuthorDB.SetWindowText(*strTemp);

        strTemp.Load(IDC_TCP_EXTERNAL);
        m_TCPExternal.SetWindowText(*strTemp);

        strTemp.Load(IDC_UDP_TO_MASTER);
        m_UDPListenMaster.SetWindowText(*strTemp);

        m_uAuthorOnline  = 0;
        m_uAuthorTotal   = 0;
        m_uAuthorLoad    = 0;
        m_uMasterCount   = 0;
        m_uMasterOnline  = 0;
        m_uMasterTotal   = 0;
    }
    m_ServerInfo.SetWindowText(TF(""));
}

void CAuthorDlg::OnLink(Int nServerIndex, uintptr_t utData)
{
    CStringFix strTemp;
    if (nServerIndex == PAKT_CENTER)
    {
        strTemp.Load(IDC_CONNECT_CENTER);

        CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

        CStrAddr  strAddr;
        GServerLoaderInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_CENTER, CServerConfig::CFG_LOAD_NONE, strAddr);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);

        GServerLoaderInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
        strTemp.AppendFormat(TF("([%s]:%d)"), *strAddr.strIp, strAddr.usPort);

        m_ConnectCenter.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_AUTHORDB)
    {
        strTemp.Load(IDC_CONNECT_AUTHORDB);

        if (utData != 0)
        {
            CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

            CStrAddr strAddr;
            GServerLoaderInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_AUTHORDB, CServerConfig::CFG_LOAD_NONE, strAddr);
            strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);

            GServerLoaderInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
            strTemp.AppendFormat(TF("([%s]:%d)"), *strAddr.strIp, strAddr.usPort);
        }
        else
        {
            CStringFix strLoad;
            strLoad.Load(IDS_NONE_MARK);
            strTemp += strLoad;
        }

        m_ConnectAuthorDB.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_MASTER)
    {
        strTemp.Load(IDC_UDP_TO_MASTER);
        CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

        CStrAddr strAddr;
        GServerLoaderInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);
        m_UDPListenMaster.SetWindowText(*strTemp);
    }
}

void CAuthorDlg::OnUpdate(Int, uintptr_t)
{
}

void CAuthorDlg::OnSync(Int nServerIndex, uintptr_t utData)
{
    if (nServerIndex == PAKT_MASTER)
    {
        PSERVER_STATUS pStatus = reinterpret_cast<PSERVER_STATUS>(utData);
        m_uMasterTotal   = pStatus->uTotal;
        m_uMasterOnline  = pStatus->uOnline;
        m_uMasterCount   = pStatus->usLoad;
    }
    else
    {
        PSERVER_STATUS pStatus = reinterpret_cast<PSERVER_STATUS>(utData);
        m_uAuthorTotal  = pStatus->uTotal;
        m_uAuthorOnline = pStatus->uOnline;
        m_uAuthorLoad   = pStatus->usLoad / DATAD_TOPERCENT;
    }
}

void CAuthorDlg::OnSync(Int nServerIndex, CStream& Stream)
{
    assert(nServerIndex == PAKT_MASTER);

    SVR_MASTER_MAP::SVR_PAIR Pair;
    while (Stream.IsEnd() == false)
    {
        Pair.Serialize(Stream);

        LVFINDINFO find ={0};
        find.flags  = LVFI_PARAM;
        find.lParam = (LPARAM)(Pair.ullKey);
        Int nIndex  = m_MasterSvr.FindItem(&find);

        if (Pair.Value.usStatus == STATUSU_UNLINK)
        {
            if (nIndex > -1)
            {
                m_MasterSvr.DeleteItem(nIndex);
            }
        }
        else if ((Pair.Value.usStatus == STATUSU_SYNC) || (Pair.Value.usStatus == STATUSU_LINK))
        {
            if (nIndex > -1)
            {
                UpdateServerData(nServerIndex, reinterpret_cast<uintptr_t>(&Pair));
            }
            else if (Pair.Value.usStatus == STATUSU_LINK)
            {
                AddServerData(nServerIndex, reinterpret_cast<uintptr_t>(&Pair));
            }
        }
    }
}

void CAuthorDlg::OnUnlink(Int nServerIndex, uintptr_t utData)
{
    UNREFERENCED_PARAMETER(utData);
    if (nServerIndex == PAKT_CENTER)
    {
        CStringFix strTemp;
        strTemp.Load(IDC_CONNECT_CENTER);
        m_ConnectCenter.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_AUTHORDB)
    {
        CStringFix strTemp;
        strTemp.Load(IDC_CONNECT_AUTHORDB);
        m_ConnectAuthorDB.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_MASTER)
    {
        CStringFix strTemp;
        strTemp.Load(IDC_UDP_TO_MASTER);
        m_UDPListenMaster.SetWindowText(*strTemp);
    }
}

void CAuthorDlg::UpdateServerInfo(void)
{
    CStringFix strInfo;
    strInfo.Load(IDC_AUTHOR_INFO);

    CStringFix strTemp;
    strTemp.Format(*strInfo, m_uAuthorOnline, m_uAuthorTotal, m_uAuthorLoad,
                   m_uMasterCount, m_uMasterOnline, m_uMasterTotal);
    m_ServerInfo.SetWindowText(*strTemp);
}

CXListView* CAuthorDlg::GetListView(Int nServerIndex)
{
    UNREFERENCED_PARAMETER(nServerIndex);
    assert(nServerIndex == PAKT_MASTER);
    return &m_MasterSvr;
}

